﻿using System;
using System.Collections;

namespace Jeneva.Validation
{
    /// <summary>
    /// Defines validation checking routines
    /// </summary>
    public interface IChecker
    {
        /// <summary>
        /// Checks if field value is assigned
        /// </summary>
        /// <param name="fieldName">fielв name</param>
        /// <param name="target">target DTO object</param>
        /// <returns>true if assigned</returns>
        bool IsAssigned(string fieldName, Dtobase target);

        /// <summary>
        /// Checks if field value was correctly parsed
        /// </summary>
        /// <param name="fieldName">fielв name</param>
        /// <param name="target">target DTO object</param>
        /// <returns>true if parsed correctly</returns>
        bool IsValidFormat(string fieldName, Dtobase target);

        /// <summary>
        /// Checks if field value is NULL
        /// </summary>
        /// <param name="value">field value</param>
        /// <returns>true if NULL</returns>
        bool IsNull(object value);

        /// <summary>
        /// Checks if field value equals to m
        /// </summary>
        /// <param name="m">m</param>
        /// <param name="value">field value</param>
        /// <returns>true if equals</returns>
        bool IsEqualTo<T>(T m, T value) where T : IEquatable<T>;

        /// <summary>
        /// Checks if field value is equal to one of the values
        /// </summary>
        /// <param name="values">values</param>
        /// <param name="value">field value</param>
        /// <returns>true if equals</returns>
        bool IsEqualToOneOf<T>(T[] values, T value) where T : IEquatable<T>;

        /// <summary>
        /// Checks if field value is empty string
        /// </summary>
        /// <param name="value">field value</param>
        /// <returns>true if empty</returns>
        bool IsEmptyString(string value);

        /// <summary>
        /// Checks if field value length is between min and max values
        /// </summary>
        /// <param name="min">min</param>
        /// <param name="max">max</param>
        /// <param name="value">field value</param>
        /// <returns>true if is between</returns>
        bool IsLengthBetween(int min, int max, string value);

        /// <summary>
        /// Checks if field value is less than or equal to 'm'
        /// </summary>
        /// <param name="m">m</param>
        /// <param name="value">field value</param>
        /// <returns>true if less or equal</returns>
        bool IsLessOrEqualTo<T>(T m, T value) where T : struct, IComparable<T>;

        /// <summary>
        /// Checks if field value is less than 'm'. IComparable.
        /// </summary>
        /// <param name="m">m</param>
        /// <param name="value">field value</param>
        /// <returns>true if less</returns>
        bool IsLessThan<T>(T m, T value) where T : struct, IComparable<T>;

        /// <summary>
        /// Checks if field value is greater than or equal to 'm'. IComparable.
        /// </summary>
        /// <param name="m">m</param>
        /// <param name="value">field value</param>
        /// <returns>true if greater or equal</returns>
        bool IsGreaterOrEqualTo<T>(T m, T value) where T : struct, IComparable<T>;

        /// <summary>
        /// Checks if field value is greater than 'm'. IComparable.
        /// </summary>
        /// <param name="m">m</param>
        /// <param name="value">field value</param>
        /// <returns>true if greater</returns>
        bool IsGreaterThan<T>(T m, T value) where T : struct, IComparable<T>;

        /// <summary>
        /// Checks if field value collection size is between min and max values inclusively (field must implement ICollection)
        /// </summary>
        /// <param name="min">min</param>
        /// <param name="max">max</param>
        /// <param name="value">field value</param>
        /// <returns>true if is between</returns>
        bool IsCountBetween(int min, int max, ICollection value);

        /// <summary>
        /// Checks if field value qualifies to regular expression
        /// </summary>
        /// <param name="expr">regular expression</param>
        /// <param name="value">field value</param>
        /// <returns>true if qualifies</returns>
        bool IsRegex(string expr, string value);
    }
}